#-*-coding:UTF-8-*-

__author__='zhaoxp'

import os
import hashlib
import unittest

from base64 import urlsafe_b64encode as encode
from base64 import urlsafe_b64decode as decode
from ldap3 import Connection,Server

from .config import get_property

'''
ldap.server=10.99.201.86
ldap.userid=uid=admin,ou=system
ldap.passwd=secret
ldap.port=10389
ldap.baseDN=ou=users,ou=plmdeploy,dc=lenovo,dc=com
'''

_server_ip= get_property('ldap.server')
_user_id  = get_property('ldap.userid')
_passwd   = get_property('ldap.passwd')
_port     = get_property('ldap.port')
_baseDN   = get_property('ldap.baseDN')

_connection = Connection(Server(_server_ip,port=int(_port)),user=_user_id,password=_passwd,auto_bind=True)



def close_LDAP_connection():
    _connection.unbind()


def get_LDAP_info():
    return [_server_ip, _user_id, _passwd, _port, _baseDN]


def print_LDAP_info():
    print('server_ip = %s'%_server_ip)
    print('user_id   = %s'%_user_id)
    print('passwd    = %s'%_passwd)
    print('port      = %s'%_port)
    print('baseDN    = %s'%_baseDN)


def print_all_LDAP_users():
    '''
    get all LDAP users and return a list containing all

    '''
    _connection.search('ou=users,'+_baseDN,'(objectclass=person)')
    if hasattr(_connection,'entries'):
        ens=_connection.entries
        for e in ens:
            print(e)


def get_LDAP_user_list(attributes=['uid','mail','cn']):
    '''
    '''
    l=[]
    _connection.search('ou=users,'+_baseDN,'(objectclass=person)', attributes=attributes)
    if hasattr(_connection,'entries'):
        ens=_connection.entries
        for e in ens:
            l.append({'uid':str(e['uid']),'cn':str(e['cn']),'mail':str(e['mail'])})
            #l.append(e['uid'])
    return l


def check_LDAP_user_pass(username, password):
    '''
    return None when passing authentication
    else return string representing the reason
    '''
    _connection.search('ou=users,'+_baseDN, 
        '(&(uid=%s)(objectclass=person))'%username, 
        attributes=['uid', 'mail', 'userPassword'])
    if hasattr(_connection,'entries'):
        ens=_connection.entries
        if len(ens) == 1:
            pwd=str(ens[0]['userPassword'])
            if check_password(pwd,password):
                return
            else:
                return 'password(user = %s) not correct'%username
        elif len(ens) > 1:
            return 'too many users in LDAP'
    else:
        return 'unknown reason'


def check_ldap_user(username, password):
    '''
    connect to LDAP and check whether user exists
    return dict to represent result
    {
        'passed':True # True or False
        'reason':'the reason why it fails' 
        'mail':'xxx@yyy.zz'
    }
    '''
    result={'passed':None,'reason':'not defined'}
    _connection.search('ou=users,'+_baseDN, '(&(uid='+username+')(objectclass=person))', attributes=['uid', 'mail', 'userPassword'])
    if hasattr(_connection,'entries'):
        ens=_connection.entries
        if len(ens)==1:
            pwd=str(ens[0]['userPassword'])
            if check_password(pwd,password):
                result['passed']=True
                result['mail']=ens[0]['mail']
            else:
                result['passed']=False
                result['reason']='password not correct'
        elif len(ens)>1:
            result['passed']=False
            result['reason']='too many users'
    return result


def _makeSecret(password):
    salt = os.urandom(4)
    h = hashlib.sha1(password)
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt)

def check_password(challenge_password, password):
    challenge_bytes = decode(challenge_password[6:])
    digest = challenge_bytes[:20]
    salt = challenge_bytes[20:]
    hr = hashlib.sha1(password)
    hr.update(salt)
    return digest == hr.digest()

def user_existed(username):
    return _connection.search('ou=users,%s'%_baseDN, '(&(uid=%s)(objectclass=person))'%username, attributes=[])


def create_user(username, fullname, mail, password):
    '''not pass test
    '''
    return _connection.add('uid=%s,ou=users,%s'%(username, _baseDN), object_class='person', attributes={'uid':username, 'sn':username, 'cn':fullname, 'mail':mail, 'userPassword':password})
